local UIBase = require("view.UIBase")
local FightUI = class("FightUI", UIBase)
local GameUtils = require("utils.GameUtils")
local Vector3 = require("utils.Vector3")
local Vector2 = require("utils.Vector2")
local FightConst = require("const.FightConst")
local UIUtil = require("utils.UIUtil")

local ICON_WIDTH = 80
local MAX_SKILL = 4 -- 最大技能数量（普攻 加三个技能）

local AUTO_TIME = 1
local ACTION_TIME = 10

function FightUI:ctor(manager)
    self._manager = manager
    self._active = false
    self._delay = 0
    self._selectedUI = {}
    local resource = {
        path = "Prefabs/UI",
        name = "FightUI",
        canvas = 1
    }
    self._actorLastSkill = {}
    self._actorLastEntityId = {}
    FightUI.super.ctor(self, resource)
end

function FightUI:awake()
    self._rectTransform = self.gameObject:GetComponent(typeof(CS.UnityEngine.RectTransform))
    self:_initListener()
    self:_initSkillIcon()
    self._btnTimeScale.onClick:AddListener(handler(self, self._onBtnTimeScaleClick))
    self._checkAuto.onValueChanged:AddListener(handler(self, self._onCheckClick))
    self._checkAuto.isOn = false
    self._textTime.text = ""
    self._textTime.gameObject:SetActive(false)
    self._textTimeScale.text = "x" .. string.format("%d", G_Time.timeScale)
end

function FightUI:_onCheckClick(selected)
    if selected then
        if self._delay > AUTO_TIME then
            self._delay = AUTO_TIME
        end
    end
end

function FightUI:appendActorSelectUI(camp)
    if not self._curSkillId then
        return
    end
    self:_clearSelectedUI()
    local enemyActors = self._manager:getActorsByCamp(camp)
    self._selectedUIs = {}
    for i = 1, #enemyActors do
        local actor = enemyActors[i]
        local selectUI = require("gameLogic.ui.SelectedUI").new(actor)
        table.insert(self._selectedUIs, selectUI)
        selectUI:setCallback(handler(self, self.selectEntity))
    end
end

function FightUI:selectEntity(entityId)
    self._actorLastEntityId[self._curEntityId] = entityId
    self:_userSkillEnd(entityId)
end

function FightUI:setRoundText(round)
    self._textRound.text = Lang.get("lang_round_count", {count = round})
end

function FightUI:_initListener()
    self._signalUserSKillRe =
        G_SignalManager:add(SignalConst.EVENT_REQUEST_USER_SKILL, handler(self, self._onEventUserRequestSKill))
end

function FightUI:_initSkillIcon()
    self._userSkills = {}
    for i = 1, MAX_SKILL do
        local object = G_ResourceManager:loadIcon("SkillIcon")
        local icon = GameUtils.instantiateTo(self.skill.transform, object)
        icon.transform.localPosition = Vector3.new(-(i - 1) * ICON_WIDTH - 30, 25, 0)
        icon.transform.localScale = Vector3.new(0.5, 0.5, 0.5)
        local luaBehaviour = icon:GetComponent(typeof(CS.LuaBehaviour))
        local skillIcon = luaBehaviour:GetScriptEnv()
        skillIcon:setClickCallback(handler(self, self.onSkillClick))
        skillIcon:setVisible(false)
        table.insert(self._userSkills, skillIcon)
    end
end

function FightUI:start()
    self.transform:SetSiblingIndex(100)
end

function FightUI:update(dt)
    if self._active then
        self._delay = self._delay - dt
        if self._delay > 0 then
            self._textTime.text =
                Lang.get(
                "lang_round_action_time",
                {
                    sec = math.ceil(self._delay)
                }
            )
        else
            self:_userSkillEnd(self._actorLastEntityId[self._curEntityId])
            self._textTime.gameObject:SetActive(false)
        end
    end
end

function FightUI:showUI(visible)
    self.rootUI:SetActive(visible)
end

function FightUI:_popSkillTip(id)
    if self._skillPop and self._curSkillId == id then
        self._skillPop:close()
    else
        self._skillPop =
            require("view.popup.PopupSkillTip").new(
            id,
            function()
                self._skillPop = nil
            end
        )
    end
end

function FightUI:onSkillClick(id)
    if not self._active then
        G_UIManager:showTip(Lang.get("not_in_action_round"))
        return
    end
    self:_popSkillTip(id)
    local config = require("config.fight_skill").get(id)
    if config.target == FightConst.SKILL_TARGET_RANDOM and self._curSkillId == id then
        self:_userSkillEnd()
    elseif config.target == FightConst.SKILL_TARGET_CALL and self._curSkillId == id then
        self:_userSkillEnd()
    else
        local camp = 0
        if config.attack_idx == FightConst.TARGET_ENEMY then
            camp = FightConst.ENEMY_STANDING
        elseif config.attack_idx == FightConst.TARGET_FRIEND then
            camp = FightConst.FRIEND_STANDING
        end
        self:appendActorSelectUI(camp)
    end
    self:updateSkillSelected(id)
    self._curSkillId = id
end

function FightUI:_userSkillEnd(entityId)
    if not self._active or not self._curSkillId then
        return
    end
    self:_clearSelectedUI()
    self:_hideSkills()
    local param = {}
    param.skillId = self._curSkillId
    param.targetEntityId = entityId
    self._actorLastSkill[self._curEntityId] = self._curSkillId
    G_SignalManager:dispatch(SignalConst.EVENT_RECEIVE_USER_SKILL, param)
    self:_resetData()
end

function FightUI:_resetData()
    self._textTime.gameObject:SetActive(false)
    self._active = false
    self._actorArrow:close()
    self._actorArrow = nil
    self._selectedUIs = nil
    self._curSkillId = nil
    self._curEntityId = nil
end

function FightUI:_clearSelectedUI()
    if self._selectedUIs then
        for i = 1, #self._selectedUIs do
            self._selectedUIs[i]:close()
        end
    end
end

function FightUI:_onEventUserRequestSKill(id, param)
    self._active = true
    if self._checkAuto.isOn then
        self._delay = AUTO_TIME
    else
        self._delay = ACTION_TIME
    end
    self._textTime.gameObject:SetActive(true)

    local userSkills = param.skills
    local entityId = param.entityId
    self._curEntityId = param.entityId
    if self._actorLastSkill[entityId] then
        self._curSkillId = self._actorLastSkill[entityId]
    else
        self._curSkillId = userSkills[1]:getId()
    end

    local actor = self._manager:findActorbyId(entityId)
    if self._actorArrow then
        self._actorArrow:close()
        self._actorArrow = nil
    end
    self._actorArrow = require("gameLogic.ui.HeroArrow").new(actor)

    for i = 1, 4 do
        local data = userSkills[i]
        if data then
            self._userSkills[i]:setVisible(true)
            self._userSkills[i]:updateUI(data:getId())
        else
            self._userSkills[i]:setVisible(false)
        end
    end
    self:updateSkillSelected(self._actorLastSkill[self._curEntityId])
end

function FightUI:updateSkillSelected(selectId)
    for i = 1, 4 do
        local icon = self._userSkills[i]
        icon:setSelected(selectId == icon:getId())
    end
end

function FightUI:_hideSkills()
    for i = 1, MAX_SKILL do
        self._userSkills[i]:setVisible(false)
    end
end

function FightUI:onDestroy()
    G_Time.timeScale = 1
    self._signalUserSKillRe:remove()
    self._signalUserSKillRe = nil
end

function FightUI:_onBtnTimeScaleClick()
    local timeScale = (G_Time.timeScale % 10) + 1
    G_Time.timeScale = timeScale
    self._textTimeScale.text = "x" .. string.format("%d", timeScale)
end

function FightUI:_onBtnQuitClick()
    self._manager:delete()
end

function FightUI:close()
    GameUtils.destroy(self.gameObject)
end

return FightUI
